home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / devices / rdf.1 < prev   
Text File  |  1988-11-29  |  53KB  |  1,346 lines

  1. Path: xanth!nic.MR.NET!tank!ncar!mailrus!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i066:  rdf - raw floppy disk handler
  5. Message-ID: <10362@swan.ulowell.edu>
  6. Date: 29 Nov 88 01:16:36 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 1335
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: u211344@hnykun11.bitnet (Olaf 'Rhialto' Seibert)
  12. Posting-number: Volume 2, Issue 66
  13. Archive-name: devices/rdf.1
  14.  
  15. Raw trackdisk.device interface for DOS, based somewhat on Matthew
  16. Dillon's excellent PIPE:.  This first version handle packets one at a
  17. time, so we avoid problems with having several IO requests
  18. outstanding (which must be replied to the reader/writer in order).
  19.  
  20. Implemented functions are:
  21.    Open() Close() Read() Write() Seek()
  22.  
  23. Usage:
  24.      RDF:/dtrackdisk.device
  25.          /uunit #
  26.          /fflags
  27.          /ooffset
  28.          /llength
  29.          /eeof  (maintain a virtual end-of-file)
  30.          /E     (get eof from last closed file)
  31.  
  32. [uuencoded doc because it's got escape sequences in it.  ..Bob]
  33.  
  34. #    This is a shell archive.
  35. #    Remove everything above and including the cut line.
  36. #    Then run the rest of the file through sh.
  37. #----cut here-----cut here-----cut here-----cut here----#
  38. #!/bin/sh
  39. # shar:    Shell Archiver
  40. #    Run the following text with /bin/sh to create:
  41. #    Makefile
  42. #    Mountlist
  43. #    Notice
  44. #    RCopy.c
  45. #    include.c
  46. #    misc.c
  47. #    rdf.c
  48. #    rdf.man.uu
  49. # This archive created: Mon Nov 28 20:05:56 1988
  50. cat << \SHAR_EOF > Makefile
  51. #DB     = -DDEBUG
  52. CFLAGS    = +BCDL +Isyms $(DB)
  53. OBJ    = rdf.o misc.o
  54.  
  55. .c.o:
  56.     cc $(CFLAGS) $*.c
  57.  
  58. .c.asm:
  59.     cc $(CFLAGS) -at $*.c
  60.  
  61. RDF-Handler:    $(OBJ)
  62.     ln $(OBJ) -lcl32 -w -o RDF-Handler
  63.  
  64. syms:    include.c
  65.     cc +BCDL +Hsyms -a -o nil: include.c
  66.  
  67. RCopy:    RCopy.c
  68.     cc RCopy.c
  69.     ln RCopy.o -lc
  70. SHAR_EOF
  71. cat << \SHAR_EOF > Mountlist
  72. RDF:       Handler = devs:RDF-Handler
  73.        Device = trackdisk.device
  74.        Unit = 1
  75.        Flags = 0
  76.        Stacksize = 4096
  77.        Priority = 4
  78.        GlobVec  = -1
  79. #
  80. SHAR_EOF
  81. cat << \SHAR_EOF > Notice
  82.  
  83. This software is (C) Copyright 1988 by Olaf Seibert. All Rights Reserved.
  84.  
  85. This software is NOT in the public domain. It may not be sold or used for
  86. profit without prior written consent from the author, Olaf Seibert.
  87.  
  88. Conditions for redistribution are:
  89.  
  90. - This notice must remain included at all times. It may not be modified in
  91.   any way.
  92.  
  93. - No charge may be made for distribution above media and transportation
  94.   costs.
  95.  
  96. - The source and documentation of the program must always be distributed
  97.   with the binary, unless the distributor of said binary agrees to supply
  98.   the source and documentation on request, with no expiration date on
  99.   availability of said source and documentation.
  100.  
  101. - If any part of this program (source or binary) or its documentation is
  102.   included in any other software package, either integrated or separately,
  103.   these redistribution conditions automatically apply to the entire
  104.   package, unless prior written permission is obtained from the author.
  105.  
  106. - No claim is made regarding the quality of this software or its
  107.   documentation. It is supplied purely as-is. The author cannot be held
  108.   responsible for any damages occurring directly or indirectly from using
  109.   or not using this program.
  110.  
  111. The author can be reached at:
  112.  
  113.   Olaf Seibert
  114.   p/a Beek 5
  115.   5815 CS  Merselo
  116.   The Netherlands
  117. SHAR_EOF
  118. cat << \SHAR_EOF > RCopy.c
  119. /*
  120.  *    RCOPY
  121.  *
  122.  *    Very plain copy program. No frills at all.
  123.  *    Just Open() Read() Write() and Close().
  124.  *
  125.  */
  126.  
  127. long Output(), Read(), Write(), Open();
  128. void *AllocMem();
  129.  
  130. #define MEMF_PUBLIC    (1L << 0)
  131. #define MEMF_CHIP    (1L << 1)
  132. #define MODE_OLDFILE    1005L
  133. #define MODE_NEWFILE    1006L
  134.  
  135. #define BUFSIZE     (11 * 1024L)
  136.  
  137. main(argc, argv)
  138. int argc;
  139. char **argv;
  140. {
  141.     register long from, to, size, output;
  142.     register void *buffer;
  143.  
  144.     output = Output();
  145.  
  146.     if (argc != 3) {
  147.     Write(output, "Usage: RCOPY source dest\n", 26L);
  148.     exit(10);
  149.     }
  150.  
  151.     if (buffer = AllocMem(BUFSIZE, MEMF_CHIP | MEMF_PUBLIC)) {
  152.     if (from = Open(argv[1], MODE_OLDFILE)) {
  153.         if (to = Open(argv[2], MODE_NEWFILE)) {
  154.         while ((size = Read(from, buffer, BUFSIZE)) > 0) {
  155.             if (size != Write(to, buffer, size)) {
  156.             Write(output, "Write error\n", 12L);
  157.             break;
  158.             }
  159.             if (Chk_Abort()) {
  160.             Write(output, "^C\n", 3L);
  161.             break;
  162.             }
  163.         }
  164.         Close(to);
  165.         } else
  166.            Write(output, "Cannot open destination\n", 24L);
  167.         Close(from);
  168.     } else
  169.         Write(output, "Cannot open source\n", 19L);
  170.     FreeMem(buffer, BUFSIZE);
  171.     } else
  172.     Write(output, "Cannot allocate copy buffer\n", 28L);
  173. }
  174.  
  175. SHAR_EOF
  176. cat << \SHAR_EOF > include.c
  177. #include <exec/types.h>
  178. #include <exec/nodes.h>
  179. #include <exec/lists.h>
  180. #include <exec/ports.h>
  181. #include <exec/libraries.h>
  182. #include <exec/devices.h>
  183. #include <exec/io.h>
  184. #include <exec/memory.h>
  185. #include <devices/trackdisk.h>
  186. #include <libraries/dos.h>
  187. #include <libraries/dosextens.h>
  188. #include <libraries/filehandler.h>
  189. /*#include "xmisc.h"*/
  190. SHAR_EOF
  191. cat << \SHAR_EOF > misc.c
  192.  
  193. /*
  194.  *  MISC.C  - support routines - Phillip Lindsay (C) Commodore 1986
  195.  *  You may freely distribute this source and use it for Amiga Development -
  196.  *  as long as the Copyright notice is left intact.
  197.  *
  198.  * 30-SEP-86
  199.  *
  200.  *  major modifications by Matthew Dillon for my PIPE: and other devices,
  201.  *  but basic theorem still Phil's.
  202.  *
  203.  * 09-OKT-88
  204.  *
  205.  *  (Olaf Seibert) added provision for an external taskwait routine.
  206.  *  Changed returnpkt and returnpktplain.
  207.  */
  208.  
  209. #include <exec/types.h>
  210. #include <exec/nodes.h>
  211. #include <exec/lists.h>
  212. #include <exec/ports.h>
  213. #include <libraries/dos.h>
  214. #include <libraries/dosextens.h>
  215.  
  216. extern void returnpkt();
  217. extern char *GetMsg();
  218.  
  219. void
  220. returnpktplain(packet, myproc)
  221. struct DosPacket *packet;
  222. struct Process *myproc;
  223. {
  224.     register struct Message *mess;
  225.     register struct MsgPort *replyport;
  226.  
  227.     replyport             = packet->dp_Port;
  228.     mess             = packet->dp_Link;
  229.     packet->dp_Port         = &myproc->pr_MsgPort;
  230.     mess->mn_Node.ln_Name    = (char *)packet;
  231.     mess->mn_Node.ln_Succ    = NULL;
  232.     mess->mn_Node.ln_Pred    = NULL;
  233.     PutMsg(replyport, mess);
  234. }
  235.  
  236.  
  237. void
  238. returnpkt(packet, myproc, res1, res2)
  239. register struct DosPacket *packet;
  240. struct Process *myproc;
  241. long res1, res2;
  242. {
  243.     packet->dp_Res1         = res1;
  244.     packet->dp_Res2         = res2;
  245.     returnpktplain(packet, myproc);
  246. }
  247.  
  248.  
  249. /*
  250.  * taskwait() ... Waits for a message to arrive at your port and
  251.  *   extracts the packet address which is returned to you.
  252.  */
  253.  
  254. typedef struct Message *(*funcptr)();
  255.  
  256. struct DosPacket *
  257. taskwait(myproc)
  258. register struct Process *myproc;
  259. {
  260.     register struct MsgPort *myport;
  261.     register struct Message *mymess;
  262.  
  263.     if (myproc->pr_PktWait) {
  264.     /* As per AmigaDOS tech. ref. man (V1.1) page 265: */
  265.     /* ``In the same way as GetMsg, the function should */
  266.     /*   return a message when one is available.'' */
  267.     mymess = (*(funcptr)myproc->pr_PktWait)(myproc);
  268.     } else {
  269.     myport = &myproc->pr_MsgPort;
  270.     WaitPort(myport);
  271.     mymess = (struct Message *)GetMsg(myport);
  272.     }
  273.     return((struct DosPacket *)mymess->mn_Node.ln_Name);
  274. }
  275.  
  276. taskpktrdy(myproc)
  277. struct Process *myproc;
  278. {
  279.     if (myproc->pr_MsgPort.mp_MsgList.lh_Tail == NULL)
  280.     return(0);
  281.     return(1);
  282. }
  283.  
  284. SHAR_EOF
  285. cat << \SHAR_EOF > rdf.c
  286. /*
  287.  *      Raw trackdisk.device interface for DOS.
  288.  *
  289.  *      Based somewhat on Mattew Dillons excellent PIPE: (hello Matt!).
  290.  *
  291.  *      First version: handle packets one at a time. This way, we avoid
  292.  *      problems with having several IO requests outstanding, which
  293.  *      must be replied to the reader/writer in order.
  294.  *
  295.  *      Usage:
  296.  *              RDF:/dtrackdisk.device
  297.  *                  /uunit #
  298.  *                  /fflags
  299.  *                  /ooffset
  300.  *                  /llength
  301.  *                  /eeof  (maintain a virtual end-of-file)
  302.  *                  /E     (get eof from last closed file)
  303.  *
  304.  *      If you open a file with /E and then read at least
  305.  *      4 bytes from it, you will get the eof offset from the last closed
  306.  *      file.
  307.  *
  308.  *      Implemented functions are:
  309.  *
  310.  *      Open() Close()
  311.  *      Read() Write()
  312.  *      Seek()
  313.  *
  314.  *      These are more or less just dummies:
  315.  *
  316.  *      Lock() UnLock() DupLock()
  317.  *      DeleteFile()
  318.  */
  319.  
  320. #include <exec/types.h>
  321. #include <exec/nodes.h>
  322. #include <exec/lists.h>
  323. #include <exec/ports.h>
  324. #include <exec/libraries.h>
  325. #include <exec/devices.h>
  326. #include <exec/io.h>
  327. #include <exec/memory.h>
  328. #include <devices/trackdisk.h>
  329. #include <libraries/dos.h>
  330. #include <libraries/dosextens.h>
  331. #include <libraries/filehandler.h>
  332.  
  333.                                             /* Various ACTION's supported */
  334. #define ACTION_FIND_RW      1004            /* name ??                  */
  335. #define ACTION_FIND_INPUT   MODE_OLDFILE    /* 1005                     */
  336. #define ACTION_FIND_OUTPUT  MODE_NEWFILE    /* 1006                     */
  337. #define ACTION_END          1007
  338. #define ACTION_SEEK         1008
  339.  
  340. #undef  BADDR
  341. #define BADDR(x)   ((APTR)((long)x << 2))   /* convert BCPL->APTR       */
  342.  
  343. #define DOS_FALSE    0
  344. #define DOS_TRUE     -1
  345.  
  346. #define TD_SECMASK  (TD_SECTOR - 1)         /* Assumes it is a power of 2 */
  347.  
  348. #define branchto    goto                    /* (-: Avoid goto's :-)     */
  349.  
  350. typedef struct DosPacket    DOSPACKET;
  351. typedef struct Process      PROC;
  352. typedef struct DeviceNode   DEVNODE;
  353. typedef struct FileHandle   FH;
  354. typedef unsigned char uchar;
  355. typedef struct Message      MSG;
  356.  
  357. typedef struct _FILE {
  358.     struct IOExtTD *file_IO;
  359.     ULONG           file_MinOffset;         /* <= Offset    */
  360.     ULONG           file_Offset;            /* <= EofOffset */
  361.     ULONG           file_EofOffset;         /* <= MaxOffset */
  362.     ULONG           file_MaxOffset;
  363. } File;
  364.  
  365. /*
  366.  * NOTE: Globals in the Bss space are not automatically initialized to
  367.  * 0 when you don't use Aztec's startup _main, which we can't since
  368.  * this is a packet handler.
  369.  */
  370.  
  371. extern long AbsExecBase;            /* Absolute global address 4    */
  372. extern DOSPACKET *taskwait();       /* wait for a message           */
  373. extern void *AllocMem();
  374. extern PROC *FindTask();
  375. extern struct IOExtTD *CreateExtIO();
  376. extern struct MsgPort *CreatePort();
  377.  
  378. ULONG PerformIO();                  /* Encapsulate DoIO()           */
  379. long ntoi();                        /* Our own fancy atoi()         */
  380.  
  381. long SysBase;                       /* required to make Exec calls  */
  382. uchar Buf[256];                     /* Scratch buffer               */
  383. long DOSBase;
  384. #ifdef DEBUG
  385. long Fh;                            /* Debugging..                  */
  386. #endif
  387.  
  388. exec_handler()
  389. {
  390.     PROC        *MyProc;        /* my process                             */
  391.     DEVNODE     *MyNode;        /* our device node passed in parmpkt Arg3 */
  392.     uchar       Expunge = 0;
  393.     uchar       NotDone;
  394.     uchar      *default_Device;
  395.     ULONG       default_Unit;
  396.     ULONG       default_Flags;
  397.     ULONG       OpenCount = 0;  /* must be 4 bytes... used as temp BPTR   */
  398.     char       *TDBuffer = NULL;
  399.     ULONG       save_Eof = 0;
  400.     struct MsgPort *IOPort;
  401.  
  402.     SysBase = AbsExecBase;      /* Initialize SysBase                     */
  403. #ifdef DEBUG
  404.     Fh = NULL;                  /* Debugging OFF                          */
  405. #endif
  406.  
  407.     MyProc  = (PROC *)FindTask(0L);
  408.  
  409.     DOSBase = OpenLibrary("dos.library", 0);
  410. #ifdef DEBUG
  411.     /*  DEBUGGING
  412.      *  Note that the debugging uses normal DOS calls, so the same
  413.      *  MsgPort is being used that our own commands arrive on.
  414.      *  So when debugging is enabled, please have only one open file
  415.      *  on RDF: at a time, or face the dreaded AN_AsyncPkt guru.
  416.      */
  417.     Fh = Open("CON:0/0/600/150/RDF-handler", MODE_NEWFILE);
  418. #endif
  419.  
  420.     /*
  421.      * INITIAL STARTUP MESSAGE
  422.      */
  423.  
  424.     {
  425.         register DOSPACKET *MyPkt;
  426.         /* long *environ; */
  427.  
  428.         MyPkt  = taskwait(MyProc);
  429.         IOPort = CreatePort(0, 0);
  430.         TDBuffer = AllocMem(TD_SECTOR, MEMF_PUBLIC | MEMF_CHIP);
  431.         if (IOPort && TDBuffer) {
  432.             struct FileSysStartupMsg *fssm;
  433.  
  434.             MyNode  = (DEVNODE *)BADDR(MyPkt->dp_Arg3);
  435.             fssm = (struct FileSysStartupMsg *)BADDR(MyNode->dn_Startup);
  436.                                     /* Same as BADDR(MyPkt->dp_Arg2) */
  437.             default_Device = (uchar *)BADDR(fssm->fssm_Device) + 1;
  438.             default_Unit   = fssm->fssm_Unit;
  439.             default_Flags  = fssm->fssm_Flags;
  440.  
  441.             MyNode->dn_Task = &MyProc->pr_MsgPort;
  442.             returnpkt(MyPkt, MyProc, DOS_TRUE, 0);
  443.         } else {
  444.             returnpkt(MyPkt, MyProc, DOS_FALSE, ERROR_NO_FREE_STORE);
  445.             Alert(0x00018014, 0); /* AG_NoMemory | AO_TrackDiskDev */
  446.             branchto exit;
  447.         }
  448. #ifdef DEBUG
  449.         if (Fh) {
  450.             sprintf(Buf, "'%s', %ld flags %ld\n",
  451.                 default_Device, default_Unit, default_Flags);
  452.             Write(Fh, Buf, strlen(Buf));
  453.         }
  454. #endif
  455.     }
  456.  
  457. top:
  458.  
  459.     /*
  460.      * MAIN LOOP
  461.      */
  462.  
  463.     NotDone = 1;
  464.     while (NotDone) {
  465.         register DOSPACKET *MyPkt;      /* dos packet received      */
  466.         register File *file;            /* pointer to current File  */
  467.         struct IOExtTD *iotd;
  468.         long type;                      /* type of packet           */
  469.  
  470.         MyPkt = taskwait(MyProc);       /* wait/get next packet     */
  471.         MyPkt->dp_Res1 = DOS_TRUE;      /* default return value     */
  472.         MyPkt->dp_Res2 = 0;             /* default no error         */
  473.         type = MyPkt->dp_Type;          /* packet type              */
  474.  
  475.         /*
  476.          *  Extract File pointer.  Doesn't apply to Open()
  477.          */
  478.  
  479.         file = (File *)MyPkt->dp_Arg1;
  480.  
  481. #ifdef DEBUG
  482.         if (Fh) {
  483.             sprintf(Buf, "Packet: %4ld arg3 %ld, file: %-8lx arg2: %ld\n",
  484.                     MyPkt->dp_Type, MyPkt->dp_Arg3, file, MyPkt->dp_Arg2);
  485.             Write(Fh, Buf, strlen(Buf));
  486.         }
  487. #endif
  488.  
  489.         switch(type) {
  490.         case ACTION_FIND_INPUT:
  491.         case ACTION_FIND_OUTPUT:
  492.         case ACTION_FIND_RW:
  493.             {
  494.                 uchar *this_Device = default_Device;
  495.                 long this_Unit = default_Unit;
  496.                 long these_Flags = default_Flags;
  497.                 long this_Offset = 0;
  498.                 long this_Length = 880 * 1024L;
  499.                 long this_Eof = -1;
  500.                 register uchar *name = (uchar *)BADDR(MyPkt->dp_Arg3);
  501.  
  502.                 /* Parse the given filename */
  503.                 strncpy(Buf, name + 1, *name);
  504.                 Buf[*name] = '\0';
  505. #ifdef DEBUG
  506.                 if (Fh) {
  507.                     Write(Fh, Buf, strlen(Buf));
  508.                     Write(Fh, "\n", 1);
  509.                 }
  510. #endif
  511.  
  512.                 for (name = Buf; *name; ) {
  513.                     if (*name == '/') {
  514.                         *name++ = '\0';
  515.                         switch (*name) {
  516.                         case 'd':
  517.                             this_Device = ++name;
  518.                             break;
  519.                         case 'u':
  520.                             this_Unit = ntoi(++name);
  521.                             break;
  522.                         case 'f':
  523.                             these_Flags = ntoi(++name);
  524.                             break;
  525.                         case 'o':
  526.                             this_Offset = ntoi(++name);
  527.                             break;
  528.                         case 'l':
  529.                             this_Length = ntoi(++name);
  530.                             break;
  531.                         case 'e':
  532.                             this_Eof = ntoi(++name);
  533.                             break;
  534.                         case 'E':
  535.                             this_Offset = -1;
  536.                         }
  537.                     } else
  538.                         name++;     /* Don't fail on /e/o */
  539.                 }
  540.  
  541.                 file = (File *)AllocMem(sizeof(File), MEMF_CLEAR);
  542.                     if (file == NULL) branchto openfail1;
  543.                 iotd = CreateExtIO(IOPort, sizeof(struct IOExtTD));
  544.                     if (iotd == NULL) branchto openfail2;
  545.                 if (OpenDevice(this_Device, this_Unit, iotd, these_Flags))
  546.                     branchto openfail3;
  547.                 iotd->iotd_Count = PerformIO(iotd, TD_CHANGENUM, 0, 0, 0);
  548.                 OpenCount++;
  549.                 file->file_IO = iotd;
  550.                 file->file_MinOffset = this_Offset;
  551.                 file->file_Offset = this_Offset;
  552.                 file->file_MaxOffset = this_Offset + this_Length;
  553.                 if (this_Eof == -1)
  554.                     file->file_EofOffset = file->file_MaxOffset;
  555.                 else
  556.                     file->file_EofOffset = this_Offset + this_Eof;
  557.             }
  558.             {
  559.                 struct FileHandle *fh;
  560.                 fh = (FH *)BADDR(MyPkt->dp_Arg1);       /* File handle  */
  561.                 fh->fh_Arg1 = (long) file;
  562.             }
  563. #ifdef DEBUG
  564.             if (Fh) {
  565.                 sprintf(Buf, "Open File %08lx iotd: %08lx\n", file, iotd);
  566.                 Write(Fh, Buf, strlen(Buf));
  567.             }
  568. #endif
  569.             branchto returnpkt;
  570.  
  571. openfail4:
  572.             CloseDevice(iotd);
  573. openfail3:
  574.             DeleteExtIO(iotd);
  575. openfail2:
  576.             FreeMem(file, sizeof(*file));
  577. openfail1:
  578.             returnpkt(MyPkt, MyProc, DOS_FALSE, ERROR_NO_FREE_STORE);
  579.             break;
  580.  
  581. returnpkt:
  582.             returnpktplain(MyPkt, MyProc);
  583.             break;
  584.  
  585.         case ACTION_END:                            /* CLOSE    */
  586.             iotd = file->file_IO;
  587. #ifdef DEBUG
  588.             if (Fh) {
  589.                 sprintf(Buf, "Close File %08lx iotd: %08lx\n", file, iotd);
  590.                 Write(Fh, Buf, strlen(Buf));
  591.             }
  592. #endif
  593.             PerformIO(iotd, CMD_UPDATE, 0, 0, 0);
  594.             PerformIO(iotd, TD_MOTOR, 0, 0, 0);
  595.             CloseDevice(iotd);
  596.             DeleteExtIO(iotd);
  597.             save_Eof = file->file_EofOffset - file->file_MinOffset;
  598.             FreeMem(file, sizeof(*file));
  599.             returnpktplain(MyPkt, MyProc);
  600.             --OpenCount;
  601.             break;
  602.  
  603.         case ACTION_READ:                   /* Arg2: buffer */
  604.             iotd = file->file_IO;
  605.             {                               /* Arg3: size   */
  606.                 char *buffer = (char *) MyPkt->dp_Arg2;
  607.                 long size = MyPkt->dp_Arg3;
  608.                 long done = 0;
  609.                 int blockoffset = 0;
  610. #ifdef DEBUG
  611.                 if (Fh) {
  612.                     sprintf(Buf, "Read File %08lx iotd: %08lx\n", file, iotd);
  613.                     Write(Fh, Buf, strlen(Buf));
  614.                     sprintf(Buf, " buffer %08lx  size %08lx offset %08lx\n",
  615.                       buffer, size, file->file_Offset);
  616.                     Write(Fh, Buf, strlen(Buf));
  617.                 }
  618. #endif
  619.                 /* Is this such a special read-last-eof file? */
  620.                 if ((LONG) file->file_Offset < 0) {
  621.                     if (size >= 4) {
  622.                         movmem(&save_Eof, buffer, 4);
  623.                         MyPkt->dp_Res1 = 4;
  624.                     } else
  625.                         MyPkt->dp_Res1 = 0;
  626.                     file->file_Offset = 0;
  627.                     file->file_EofOffset = 0;
  628.                     branchto readdone;
  629.                 }
  630.  
  631.                 /* Don't read past the end of the virtual file */
  632.                 done = file->file_EofOffset - file->file_Offset;
  633.                 if (size > done) size = done;
  634.                 MyPkt->dp_Res1 = size;
  635.  
  636.                 blockoffset = file->file_Offset & TD_SECMASK;
  637.  
  638.                 /* Can we read directly into the user buffer? */
  639.                 if ((size >= TD_SECTOR) &&
  640.                     blockoffset == 0 &&
  641.                     (size & 3) == 0 && (((long)buffer) & 3) == 0 &&
  642.                     (TypeOfMem(buffer) & MEMF_CHIP)) {
  643.                     done = PerformIO(iotd, ETD_READ, buffer,
  644.                            file->file_Offset, size & ~TD_SECMASK);
  645.                     if (iotd->iotd_Req.io_Error)
  646.                         branchto readfail;
  647.                     file->file_Offset += done;
  648.                     buffer += done;
  649.                     size -= done;
  650.                 }
  651.                 /* Read the rest (or all of it) via our MEMF_CHIP buffer */
  652.                 while (size > 0) {
  653.                     /* Get one disk block: do a bit of padding at the start */
  654.                     done = PerformIO(iotd, ETD_READ, TDBuffer,
  655.                            file->file_Offset - blockoffset, TD_SECTOR)
  656.                          - blockoffset;         /* and subtract the padding */
  657.                     if (iotd->iotd_Req.io_Error || done <= 0) {
  658. readfail:
  659.                         MyPkt->dp_Res1 = -1;
  660.                         MyPkt->dp_Res2 = ERROR_READ_PROTECTED; /* Silly */
  661.                         break;
  662.                     }
  663.                     /* Don't copy more than the user wanted */
  664.                     if (done > size) done = size;
  665.                     movmem(TDBuffer + blockoffset, buffer, done);
  666.                     file->file_Offset += done;
  667.                     /* Normally the block offset becomes 0 now */
  668.                     blockoffset = file->file_Offset & TD_SECMASK;
  669.                     buffer += done;
  670.                     size -= done;
  671.                 }
  672. readdone: ;
  673. #ifdef DEBUG
  674.                 if (Fh) {
  675.                     sprintf(Buf, " Read: %ld DoIO: %ld size left: %lx\n",
  676.                       MyPkt->dp_Res1, iotd->iotd_Req.io_Error, size);
  677.                     Write(Fh, Buf, strlen(Buf));
  678.                 }
  679. #endif
  680.             }
  681.             branchto returnpkt;
  682.  
  683.         case ACTION_WRITE:
  684.             iotd = file->file_IO;
  685.             {
  686.                 char *buffer = (char *) MyPkt->dp_Arg2;
  687.                 long size = MyPkt->dp_Arg3;
  688.                 long done = 0;
  689.                 int blockoffset = 0;
  690. #ifdef DEBUG
  691.                 if (Fh) {
  692.                     sprintf(Buf, "Write File %08lx iotd: %08lx\n", file,iotd);
  693.                     Write(Fh, Buf, strlen(Buf));
  694.                     sprintf(Buf, " buffer %08lx  size %08lx offset %08lx\n",
  695.                       buffer, size, file->file_Offset);
  696.                     Write(Fh, Buf, strlen(Buf));
  697.                 }
  698. #endif
  699.                 /* Don't write past the end of the device */
  700.                 done = file->file_MaxOffset - file->file_Offset;
  701.                 if (size > done) {
  702.                     size = done;
  703.                     MyPkt->dp_Res2 = ERROR_DISK_FULL;
  704.                 }
  705.                 MyPkt->dp_Res1 = size;
  706.  
  707.                 blockoffset = file->file_Offset & TD_SECMASK;
  708.  
  709.                 /* Can we write directly into the user buffer? */
  710.                 if ((size >= TD_SECTOR) &&
  711.                     blockoffset == 0 &&
  712.                     (size & 3) == 0 && (((long)buffer) & 3) == 0 &&
  713.                     (TypeOfMem(buffer) & MEMF_CHIP)) {
  714.                     done = PerformIO(iotd, ETD_WRITE, buffer,
  715.                            file->file_Offset, size & ~TD_SECMASK);
  716.                     if (iotd->iotd_Req.io_Error)
  717.                         branchto writefail;
  718.                     file->file_Offset += done;
  719.                     buffer += done;
  720.                     size -= done;
  721.                 }
  722.  
  723.                 /* Write the rest (or all of it) via our MEMF_CHIP buffer */
  724.                 while (size > 0) {
  725.                     /* Get a partial disk block */
  726.                     if (blockoffset || size < TD_SECTOR) {
  727.                         PerformIO(iotd, ETD_READ, TDBuffer,
  728.                                   file->file_Offset - blockoffset, TD_SECTOR);
  729.                         if (iotd->iotd_Req.io_Error)
  730.                             branchto writefail;
  731.                     }
  732.  
  733.                     if (blockoffset + size > TD_SECTOR)
  734.                         done = TD_SECTOR - blockoffset;
  735.                     else
  736.                         done = size;
  737.                     movmem(buffer, TDBuffer + blockoffset, done);
  738.  
  739.                     /* Write the buffer (back) */
  740.                     PerformIO(iotd, ETD_WRITE, TDBuffer,
  741.                               file->file_Offset - blockoffset, TD_SECTOR);
  742.  
  743.                     /* On error we did not write the block */
  744.                     if (iotd->iotd_Req.io_Error ||
  745.                         iotd->iotd_Req.io_Actual != TD_SECTOR) {
  746. writefail:
  747.                         MyPkt->dp_Res1 = -1;
  748.                         MyPkt->dp_Res2 = ERROR_WRITE_PROTECTED; /* Silly */
  749.                         break;
  750.                     }
  751.  
  752.                     file->file_Offset += done;
  753.                     /* Normally the block offset becomes 0 now */
  754.                     blockoffset = file->file_Offset & TD_SECMASK;
  755.                     buffer += done;
  756.                     size -= done;
  757.                 }
  758. #ifdef DEBUG
  759.                 if (Fh) {
  760.                     sprintf(Buf, " Write: %ld DoIO: %ld size left: %lx\n",
  761.                       MyPkt->dp_Res1, iotd->iotd_Req.io_Error, size);
  762.                     Write(Fh, Buf, strlen(Buf));
  763.                 }
  764. #endif
  765.             }
  766.  
  767.             /* Writing may adjust the end-of-file marker */
  768.             if (file->file_Offset > file->file_EofOffset)
  769.                file->file_EofOffset = file->file_Offset;
  770.             branchto returnpkt;
  771.  
  772.         case ACTION_RENAME_DISK:  /* for debugging */
  773.         case ACTION_DIE:
  774.             Expunge = 1;
  775.             if (OpenCount == 0) NotDone = 0;
  776.             branchto returnpkt;
  777.  
  778.         case ACTION_SEEK:
  779.             {
  780.                 long Offset = -1;
  781.  
  782.                 switch (MyPkt->dp_Arg3) {   /* seek mode */
  783.                 case OFFSET_BEGINNING:
  784.                     Offset = file->file_MinOffset + MyPkt->dp_Arg2;
  785.                     break;
  786.                 case OFFSET_CURRENT:
  787.                     Offset = file->file_Offset + MyPkt->dp_Arg2;
  788.                     break;
  789.                 case OFFSET_END:
  790.                     Offset = file->file_EofOffset + MyPkt->dp_Arg2;
  791.                     break;
  792.                 }
  793.                 if (Offset >= file->file_MinOffset &&
  794.                     Offset <= file->file_EofOffset) {
  795.                     MyPkt->dp_Res1 = Offset - file->file_MinOffset;
  796.                     file->file_Offset = Offset;
  797.                 } else {
  798.                     MyPkt->dp_Res1 = -1;
  799.                     MyPkt->dp_Res2 = ERROR_SEEK_ERROR;
  800.                 }
  801.             }
  802.             branchto returnpkt;
  803.  
  804.         case ACTION_LOCATE_OBJECT:  /* Just always succeed */
  805.             {
  806.                 struct FileLock *lock;
  807.  
  808.                 if (lock = AllocMem(sizeof (*lock), MEMF_PUBLIC | MEMF_CLEAR))
  809.                 {
  810.                     lock->fl_Access = MyPkt->dp_Arg3;
  811.                     lock->fl_Task = &MyProc->pr_MsgPort;
  812.                     /* lock->fl_Volume remains NULL */
  813.                     OpenCount++;
  814.                 } else
  815.                     MyPkt->dp_Res2 = ERROR_NO_FREE_STORE;
  816.                 MyPkt->dp_Res1 = ((long) lock) >> 2;
  817.             }
  818.             branchto returnpkt;
  819.  
  820.         case ACTION_COPY_DIR:
  821.             {
  822.                 struct FileLock *lock;
  823.  
  824.                 if (lock = AllocMem(sizeof (*lock), MEMF_PUBLIC | MEMF_CLEAR)) {
  825.                     *lock = *(struct FileLock *)BADDR(MyPkt->dp_Arg1);
  826.                     OpenCount++;
  827.                 } else
  828.                     MyPkt->dp_Res2 = ERROR_NO_FREE_STORE;
  829.                 MyPkt->dp_Res1 = ((long) lock) >> 2;
  830.             }
  831.             branchto returnpkt;
  832.  
  833.         case ACTION_FREE_LOCK:
  834.             {
  835.                 if (MyPkt->dp_Arg1) {
  836.                     FreeMem(BADDR(MyPkt->dp_Arg1), sizeof (struct FileLock));
  837.                     OpenCount--;
  838.                 }
  839.             }
  840.             branchto returnpkt;
  841.  
  842.         default:
  843.             returnpkt(MyPkt, MyProc, DOS_FALSE, ERROR_ACTION_NOT_KNOWN);
  844.             break;
  845.         } /* end switch */
  846.     } /* end while (NotDone) */
  847.  
  848.     /*
  849.      *  Can only exit if no messages pending.  There might be a window
  850.      *  here, but there is nothing that can be done about it.
  851.      */
  852.  
  853. #ifdef DEBUG
  854.     if (!Expunge)
  855.         branchto top;
  856. #endif
  857.  
  858.     Forbid();
  859.     if (taskpktrdy(MyProc)) {
  860.         Permit();
  861.         branchto top;
  862.     }
  863.  
  864.     MyNode->dn_Task = NULL;
  865.     Permit();
  866.  
  867. exit:
  868.  
  869.     if (IOPort) DeletePort(IOPort);
  870.     if (TDBuffer) FreeMem(TDBuffer, TD_SECTOR);
  871.  
  872. #ifdef DEBUG
  873.     if (Fh) Close(Fh);
  874. #endif
  875.  
  876.     /* We are a process "so we fall off the end of the world" */
  877.  
  878.     if (Expunge) {
  879.         OpenCount = MyNode->dn_SegList;     /* Temporary */
  880.         Forbid();
  881.         MyNode->dn_SegList = NULL;
  882.         UnLoadSeg(OpenCount);
  883.         /* We execute in unallocated memory now... and Forbid()den. */
  884.     }
  885.     CloseLibrary(DOSBase);
  886.  
  887.     /* MUST fall through */
  888. }
  889.  
  890. ULONG PerformIO(ioReq, cmd, buffer, offset, size)
  891. register struct IOExtTD *ioReq;
  892. ULONG cmd;
  893. APTR  buffer;
  894. ULONG offset;
  895. ULONG size;
  896. {
  897. #ifdef DEBUG
  898.     if (Fh) {
  899.         sprintf(Buf, "PerfIO buffer %08lx  size %08lx offset %08lx\n",
  900.         buffer, size, offset);
  901.         Write(Fh, Buf, strlen(Buf));
  902.     }
  903. #endif
  904.     ioReq->iotd_Req.io_Command = cmd;
  905.     ioReq->iotd_Req.io_Length = size;
  906.     ioReq->iotd_Req.io_Data = buffer;
  907.     ioReq->iotd_Req.io_Offset = offset;
  908.     DoIO(ioReq);
  909.     return ioReq->iotd_Req.io_Actual;
  910. }
  911.  
  912. int todigit(c)
  913. register char c;
  914. {
  915.     if ((c -= '0') < 0 || c > ('F' - '0'))
  916.         return 42;
  917.  
  918.     if (c >= ('A' - '0')) {
  919.         c -= 'A' - '9' - 1;
  920.     }
  921.  
  922.     return c;
  923. }
  924.  
  925. long ntoi(str)
  926. register char *str;
  927. {
  928.     register long total = 0;
  929.     register long value;
  930.     register int digit;
  931.     register int base;
  932.  
  933.     /* First determine the base */
  934. number:
  935.     if (*str == '0') {
  936.         if (*++str == 'x') {    /* 0x means hexadecimal */
  937.             base = 16;
  938.             str++;
  939.         } else {
  940.             base = 8;           /* Otherwise, 0 means octal */
  941.         }
  942.     } else {
  943.         base = 10;              /* and any other digit means decimal */
  944.     }
  945.  
  946.     value = 0;
  947.     while ((digit = todigit(*str)) < base) {
  948.         value *= base;
  949.         value += digit;
  950.         str++;
  951.     }
  952.  
  953. suffix:
  954.     switch (*str++) {
  955.     case 'm':                   /* scale with megabytes */
  956.         value *= 1024 * 1024;
  957.         branchto suffix;
  958.     case 'k':                   /* scale with kilobytes */
  959.         value *= 1024;
  960.         branchto suffix;
  961.     case 's':                   /* scale with sectors */
  962.         value *= TD_SECTOR;     /* or maybe even kilosectors! */
  963.         branchto suffix;
  964.     case 'b':                   /* scale with bytes */
  965.         branchto suffix;
  966.     }
  967.     str--;
  968.  
  969.     total += value;
  970.  
  971.     if (*str >= '0' && *str <= '9')
  972.         branchto number;        /* Allow 10k512, recursion eliminated */
  973.  
  974.     return total;
  975. }
  976.  
  977. SHAR_EOF
  978. cat << \SHAR_EOF > rdf.man.uu
  979.  
  980. begin 644 rdf.man
  981. M"B`@("`@4D1&*#0I("`@("`@("`@("`@("`@($%M:6=A(%!R;V=R86UM97(G-
  982. M<R!-86YU86P@("`@("`@("`@("`@("`@(%)$1B@T*0H*"@H@("`@()LQ;4Y!"
  983. M344@"B`@("`@("`@("";,&UR9&8Z("T@<F%W(&EN=&5R9F%C92!T;R!D:7-K`
  984. M<R`*"B`@("`@FS%M4UE.3U!325,@"B`@("`@("`@("";,&U-;W5N="!21$8ZS
  985. M"B`@("`@("`@("!21$8Z+V0\<V]M92YD979I8V4^("`H<V5T($1E=FEC92!AD
  986. M<F=U;65N="!F;W(@3W!E;D1E=FEC92D*("`@("`@("`@("`@("`O=3QU;FET^
  987. M(",^("`@("`@("AS970@56YI="!A<F=U;65N="!F;W(@3W!E;D1E=FEC92D*T
  988. M("`@("`@("`@("`@("`O9CQF;&%G<SX@("`@("`@("AS970@1FQA9W,@87)GW
  989. M=6UE;G0@9F]R($]P96Y$979I8V4I"B`@("`@("`@("`@("`@+V\\;V9F<V5TF
  990. M/B`@("`@("`H<V5T(&EN:71I86P@;V9F<V5T(&]N(&1E=FEC92D*("`@("`@#
  991. M("`@("`@("`O;#QL96YG=&@^("`@("`@("AS970@;&5N9W1H(&]F('!H>7-I/
  992. M8V%L(&1E=FEC92D*("`@("`@("`@("`@("`O93QE;V8^("`@("`@("`@("AS6
  993. M970@86YD(&UA:6YT86EN(&$@=FER='5A;"!E;F0M;V8M9FEL92D*("`@("`@>
  994. M("`@("`@("`O12`@("`@("`@("`@("`@("AG970@96]F(&9R;VT@;&%S="!C!
  995. M;&]S960@9FEL92D*"B`@("`@("`@("!20V]P>2`\<V]U<F-E/B`\9&5S=&EN/
  996. M871I;VX^"@H@("`@()LQ;41%4T-225!424].(`H@("`@("`@("`@FS!MFS-MG
  997. M4D1&.B`@()LP;6ES("`@82`@(&1O<RUL979E;"`@('!A8VME="`@(&AA;F1LU
  998. M97(@(&EN=&5R9F%C92`@9F]R"B`@("`@("`@("!T<F%C:V1I<VLN9&5V:6-EW
  999. M+6QI:V4@97AE8R`@9&5V:6-E<RX@("`@270@(&5N86)L97,@('EO=2`@=&\*)
  1000. M("`@("`@("`@(&]P97)A=&4@;VX@82!F;&]P<'D@9&ES:R`H;W(@:68@>6]U(
  1001. M(&QI:V4L('EO=7(@:&%R9"!D:7-K*2!A<PH@("`@("`@("`@82!S97%U96YT7
  1002. M:6%L("!S=')E86T@;V8@8GET97,N("!)="!B>7!A<W-E<R!B=69F97)S('1H\
  1003. M870@87)E"B`@("`@("`@("!M86YA9V5D(&)Y('1H92!F:6QE('-Y<W1E;2`HM
  1004. M87,@861D960@8GD@("=!9&1"=69F97)S)RDL("!B=70*("`@("`@("`@(&ET,
  1005. M("!M86ME<R`@=7-E("!O9B!B=69F97)S(&UA;F%G960@8GD@82!D979I8V4@9
  1006. M8G5F9F5R(&-A8VAE+`H@("`@("`@("`@<W5C:"!A<R!&86-C(&%N9"!&86-C8
  1007. M($E)+B!9;W4@8V%N($]P96XH,BD@82!F:6QE(&]N('1H92";,VU21$8Z"B`@>
  1008. M("`@("`@("";,&UD979I8V4L(&%N9"!T:&5N(%)E860H,BD@9G)O;2!A;F0@<
  1009. M5W)I=&4H,BD@=&\@:70N("!9;W4@(&YE960*("`@("`@("`@(&YO="`@8F4@7
  1010. M(&-O;F-E<FYE9"`@86)O=70@('1H92`@<V5C=&]R("!A;&EG;FUE;G0@('1H8
  1011. M870@('1H90H@("`@("`@("`@=')A8VMD:7-K+F1E=FEC92!I;7!O<V5S.R!IB
  1012. M9B!N965D960L()LS;5)$1CH@FS!M=VEL;"!U<V4@(&ET<R`@;W=N"B`@("`@3
  1013. M("`@("!P<FEV871E("!B=69F97(@('1O("!R96%D("!O<B`@=W)I=&4@('!AQ
  1014. M<G1I86P@<V5C=&]R<R!O;B!T:&4*("`@("`@("`@(&1I<VLN("`*("`@("`@*
  1015. M("`@()LS;5)#;W!Y()LP;6ES(&$@=F5R>2!S:6UP;&4L(&YO(&9R:6QL<R`@"
  1016. M8V]P>2`@<')O9W)A;2`@=&AA="`@;VYL>0H@("`@("`@("`@=7-E<R!/<&5NB
  1017. M*"DL($-L;W-E*"DL(%)E860H*2!A;F0@5W)I=&4H*2!T;R!C;W!Y(&$@9FEL&
  1018. M92X@($ET"B`@("`@("`@("!H87,@(&)E96X@(&]P=&EM:7IE9"`@=&\@8F4@O
  1019. M=7-E9"!W:71H()LS;5)$1CH@FS!M+"!S:6YC92!I="!U<V5S(&$*("`@("`@<
  1020. M("`@(&)U9F9E<B!O9B`@,C(@("H@(%1$7U-%0U1/4B`@8GET97,@("AA("!SG
  1021. M:6YG;&4@(&-Y;&EN9&5R("!O;@H@("`@("`@("`@9FQO<'!I97,I('1H870@,
  1022. M(&ES("!L;V-A=&5D("!I;B`@0VAI<"`@;65M;W)Y+B`@("!4:&ES("!W87DL/
  1023. M"B`@("`@("`@("!U;FYE8V5S<V%R>2!M96UO<GD@8V]P>2!O<&5R871I;VYSR
  1024. M(&%R92!A=F]I9&5D+B`@"@H@("`@("`@("`@("`@("";,VU21$8Z()LP;7)EV
  1025. M8V]G;FEZ97,@<V]M92!O<'1I;VYS('1H870@>6]U("!C86X@('-P96-I9GD@U
  1026. M(&EN"B`@("`@("`@("!T:&4@9FEL92`@;F%M92`@<W5P<&QI960@('1O(&ETI
  1027. M+B`@36]S="!O<'1I;VYS(&AA=F4@9&5F875L=',*("`@("`@("`@('1H870@4
  1028. M87)E('-E="!I;B!T:&4@36]U;G1,:7-T("AS964@8F5L;W<I+B`@3W!T:6]N9
  1029. M<R`@8V]N<VES=`H@("`@("`@("`@;V8@(&$@9F]R=V%R9"!S;&%S:"P@9F]L3
  1030. M;&]W960@8GD@82!S:6YG;&4@;&5T=&5R+"!O<'1I;VYA;&QY"B`@("`@("`@*
  1031. M("!F;VQL;W=E9"!B>2!A('9A;'5E+B`@5&AE(&9O;&QO=VEN9R!O<'1I;VYS!
  1032. M(&%R92!R96-O9VYI>F5D.B`*"B`@("`@("`@("`@("`@()LS;5)$1CHO9#QS#
  1033. M;VUE($5X96,@9&5V:6-E(&YA;64^()LP;2AS970@1&5V:6-E(&%R9W5M96YTT
  1034. M("!F;W(*("`@("`@("`@($]P96Y$979I8V4I(`H@("`@("`@("`@5&AE(&YA6
  1035. M;64@>6]U('-U<'!L>2!H97)E('=I;&P@8F4@=7-E9"!I;B!T:&4@3W!E;D1EC
  1036. M=FEC92!C86QL"B`@("`@("`@("!T:&%T("!I<R`@<&%R="`@;V8@=&AE(&%C+
  1037. M=&EO;G,@;V8@;W!E;FEN9R!A(&9I;&4@;VX@=&AE()LS;5)$1CH*("`@("`@,
  1038. M("`@()LP;7!S975D;R!D979I8V4N("`@($%N>2`@17AE8R`@9&5V:6-E("!T7
  1039. M:&%T("!L;V]K<R`@;&EK92`@('1H90H@("`@("`@("`@=')A8VMD:7-K+F1EL
  1040. M=FEC92!I<R`@=F%L:60N("`@26X@<&%R=&EC=6QA<BP@FS-M4D1&.B";,&UOS
  1041. M;FQY(')E861S"B`@("`@("`@("!A;F0@('=R:71E<R`@8FQO8VMS("!O9B`@P
  1042. M(%1$7U-%0U1/4B`@(&)Y=&5S("`@;VX@("!41%]314-43U(*("`@("`@("`@\
  1043. M(&)O=6YD87)I97,N("!4:&ES(&EM<&QI97,@=&AA="`H<V5Q=65N=&EA;"D@"
  1044. M9&5V:6-E<R!L:6ME('1H90H@("`@("`@("`@<V5R:6%L+F1E=FEC92`@=VEL]
  1045. M;"`@;F]T('=O<FLL('-I;F-E(')E<&5A=&5D(')E861S('=I=&@@=&AE"B`@>
  1046. M("`@("`@("!S86UE($]F9G-E="!W:6QL('5S=6%L;'D@;F]T(')E='5R;B!TY
  1047. M:&4@<V%M92!D871A+B`@"B`@("`@("`@("!)9B!Y;W4@9&]N)W0@<W5P<&QYZ
  1048. M('1H:7,@;W!T:6]N+"!T:&4@9&5F875L="!I<R`@=&%K96X@(&9R;VT*("`@0
  1049. M("`@("`@('1H92!-;W5N=$QI<W0@96YT<GD@)T1E=FEC92`])RX@(`H*("`@_
  1050. M("`@("`@("`@("`@FS-M4D1&.B]U/'5N:70@(SX@FS!M*'-E="!5;FET(&%RQ
  1051. M9W5M96YT(&9O<B!/<&5N1&5V:6-E*2`*("`@("`@("`@(%1H:7,@56YI="!W[
  1052. M:6QL(&)E(&]P96YE9"!O;B!T:&4@<W!E8VEF:65D(&]R(&1E9F%U;'0@1&5VR
  1053. M:6-E+@H@("`@("`@("`@268@('EO=2`@9&]N)W0@<W5P<&QY('1H:7,@;W!TI
  1054. M:6]N+"!T:&4@9&5F875L="!I<R!T86ME;B!F<F]M"@H*("`@("!+;W-M;U-OD
  1055. M9G0@("`@("`@("`@("`@("`@("`@("`@("`M,2T@("`@("`@("`@("`@("`@E
  1056. M("`@("`@(%)E;&5A<V4@,2XP"@H*("`@("!21$8H-"D@("`@("`@("`@("`@/
  1057. M("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@("`@("`@("`@("`@S
  1058. M4D1&*#0I"@H*("`@("`@("`@('1H92!-;W5N=$QI<W0@96YT<GD@)U5N:70@H
  1059. M/2<N("`*"B`@("`@("`@("`@("`@()LS;5)$1CHO9CQF;&%G<SX@FS!M*'-E+
  1060. M="!&;&%G<R!A<F=U;65N="!F;W(@3W!E;D1E=FEC92D@"B`@("`@("`@("!44
  1061. M:&5S92!&;&%G<R!W:6QL(&)E('-P96-I9FEE9"!O;B!T:&4@;W!E;B!O9B`@B
  1062. M=&AE("!S<&5C:69I960*("`@("`@("`@(&]R("!D969A=6QT("!$979I8V4N[
  1063. M("!)9B`@>6]U("!D;VXG="!S=7!P;'D@=&AI<R!O<'1I;VXL('1H90H@("`@=
  1064. M("`@("`@9&5F875L="!I<R!T86ME;B!F<F]M('1H92!-;W5N=$QI<W0@96YT_
  1065. M<GD@)T9L86=S(#TG+B`@"@H@("`@("`@("`@("`@("";,VU21$8Z+V\\;V9FK
  1066. M<V5T/B";,&TH<V5T(&EN:71I86P@;V9F<V5T(&]N(&1E=FEC92D@"B`@("`@'
  1067. M("`@("!4:&ES(&]P=&EO;B!L971S('EO=2!S<&5C:69Y('=H97)E('EO=7(@C
  1068. M=FER='5A;"!F:6QE("!S=&%R=',*("`@("`@("`@(&]N('1H92`@<&AY<VEC`
  1069. M86P@(&1E=FEC92X@("`@5&AE<F4@:7,@;F\@=V%Y('EO=2!C86X@<F5A9"!OG
  1070. M<@H@("`@("`@("`@=W)I=&4@9&%T82!B969O<F4@=&AI<R!P;VEN="`@;VX@3
  1071. M('1H92`@9&ES:RX@("`@06YY("!3965K*#(I"B`@("`@("`@("!O9F9S970@>
  1072. M=VEL;"!B92!R96QA=&EV92!T;R!T:&ES('!O:6YT+B`@5&AE(&1E9F%U;'0@T
  1073. M9F]R('1H:7,*("`@("`@("`@(&]P=&EO;B!I<R`P+B`@"@H@("`@("`@("`@0
  1074. M("`@("";,VU21$8Z+VP\;&5N9W1H/B";,&TH<V5T(&QE;F=T:"!O9B!P:'ES/
  1075. M:6-A;"!D979I8V4I(`H@("`@("`@("`@5&AI<R`@;W!T:6]N("!L971S("!Y>
  1076. M;W4@('-P96-I9GD@('1H92!L96YG=&@@;V8@=&AE('!H>7-I8V%L"B`@("`@W
  1077. M("`@("!D979I8V4N("";,VU21$8Z()LP;7=O;B=T(&%T=&5M<'0@=&\@<F5A0
  1078. M9"!O<B!W<FET92!M;W)E('1H86X@('1H:7,*("`@("`@("`@(&%M;W5N="!OS
  1079. M9B`@8GET97,@('!A<W0@('1H92`@:6YI=&EA;"!O9F9S970N("!)9B!Y;W4@1
  1080. M<W!E8VEF>0H@("`@("`@("`@=&AI<R!V86QU92!T;V\@;&%R9V4@9F]R('1HR
  1081. M92!P:'ES:6-A;"`@9&5V:6-E+"`@=&AE("!$;TE/*#(I"B`@("`@("`@("!CZ
  1082. M86QL('=I;&P@<F5T=7)N(&%N(&5R<F]R+"!S;R!T:&4@4F5A9"@I(&]R(%=RP
  1083. M:71E*"D@=VEL;"!N;W0*("`@("`@("`@(')E='5R;B!T:&4@(&YU;6)E<B`@P
  1084. M;V8@(&)Y=&5S("!R97%U97-T960N("!)9B!T:&ES(&]P=&EO;B!I<PH@("`@"
  1085. M("`@("`@=7-E9"!P<F]P97)L>2P@FS-M4D1&.B";,&UW;VXG="!E=F5N("!TT
  1086. M<GD@(&1O("!A8V-E<W,@('1H92`@9&5V:6-E"B`@("`@("`@("!B97EO;F0@,
  1087. M:71S("!L:6UI="X@($]R('EO=2!C86X@;6%K92!S=7)E('1H870@;VYL>2!A^
  1088. M('!A<G0@;V8*("`@("`@("`@('1H92!D979I8V4@8V%N(&)E(&%C8V5S<V5D[
  1089. M+B`@5&AE(&1E9F%U;'0@9F]R('1H:7,@;W!T:6]N("!I<PH@("`@("`@("`@R
  1090. M.#@P:RX@(`H*("`@("`@("`@("`@("`@FS-M4D1&.B]E/&5O9CX@FS!M*'-E>
  1091. M="!A;F0@;6%I;G1A:6X@82!V:7)T=6%L(&5N9"UO9BUF:6QE*2`*("`@("`@9
  1092. M("`@(%1H:7,@(&]P=&EO;B`@<W!E8VEF:65S("!T:&%T()LS;5)$1CH@FS!MF
  1093. M<VAO=6QD(&UA:6YT86EN(&$@=FER='5A;`H@("`@("`@("`@96YD(&]F(&9I-
  1094. M;&4@;6%R:V5R+B`@5&AI<R!M86ME<R!A(&9I;&4@;VX@FS-M4D1&.B`@FS!M1
  1095. M;&]O:R`@82`@8FET"B`@("`@("`@("!M;W)E(&QI:V4@(&$@(&YO<FUA;"`@!
  1096. M9&ES:R`@9FEL92X@("!!;GD@871T96UP="!T;R!296%D*"D@;W(*("`@("`@;
  1097. M("`@(%-E96LH*2!P87-T('1H92!E;F0@;V8@9FEL92!M87)K97(@:7,@<F5J=
  1098. M96-T960N("!(;W=E=F5R+"`@80H@("`@("`@("`@5W)I=&4H*2`@<&%S="`@^
  1099. M=&AE("!E;F0@;V8@9FEL92!M87)K(&ES(&%L;&]W960L(&%N9"!I;B!T:&%T#
  1100. M"B`@("`@("`@("!C87-E('1H92!E;F0@;V8@9FEL92!I<R!U<&1A=&5D('1O9
  1101. M(')E9FQE8W0@=&AA="!T:&4@('9I<G1U86P*("`@("`@("`@(&9I;&4@:&%S$
  1102. M("!G<F]W;BX@("`@5&AI<R`@:7,@<&%R=&EC=6QA<GD@=7-E9G5L(&9O<B!P*
  1103. M<F]G<F%M<PH@("`@("`@("`@=&AA="!3965K*"D@<F5L871I=F4@=&\@=&AE/
  1104. M(&5N9"!O9B!T:&4@9FEL92X@("`@5&AE("!D969A=6QT"B`@("`@("`@("!F1
  1105. M;W(@('1H:7,@(&]P=&EO;B`@:7,@('1H92`@=F%L=64@9F]R("]L+B!)9B!YD
  1106. M;W4@<W!E8VEF>2!T:&4*("`@("`@("`@(&]P=&EO;B!W:71H;W5T(&$@=F%L3
  1107. M=64L(#`@:7,@87-S=6UE9"X@(`H*("`@("`@("`@("`@("`@FS-M4D1&.B]%+
  1108. M()LP;2AG970@96]F(&9R;VT@;&%S="!C;&]S960@9FEL92D@"B`@("`@("`@O
  1109. M("!3;VUE=&EM97,@:70@;6%Y(&)E(&YE8V5S<V%R>2!T;R!K;F]W+"!H;W<@*
  1110. M;&%R9V4@=&AE('9I<G1U86P*("`@("`@("`@(&9I;&4@:&%S(&=R;W=N+B`@4
  1111. M1F]R(&5X86UP;&4L('EO=2!M87D@;&%T97(@=V%N="!T;R!A9&0@9&%T80H@%
  1112. M("`@("`@("`@=&\@=&AE(&5N9"X@(%1H97)E9F]R92P@=&AE(&9O;&QO=VEND
  1113. M9R!H86-K('=A<R!C;VYC96EV960N("`*("`@("`@("`@($EF('EO=2!O<&5N/
  1114. M('1H92!F:6QE(%)$1CHO12!A;F0@=&AE;B!R96%D(&%T(&QE87-T(#0@(&)Y&
  1115. M=&5S+`H@("`@("`@("`@>6]U('=I;&P@9V5T('1H92!E;F0@;V8@9FEL92!V:
  1116. M86QU92!F<F]M('1H92!L87-T(&-L;W-E9"!F:6QE"B`@("`@("`@("!I;G1O.
  1117. M('EO=7(@(&)U9F9E<B`@87,@(&$@('-I9VYE9"`@;&]N9W=O<F0N("!4:&4@S
  1118. M4F5A9"@I('=I;&P*("`@("`@("`@(')E='5R;B`T(&EN('1H:7,@8V%S92X@\
  1119. M($]T:&5R=VES92!T:&4@4F5A9"@I('=I;&P@<F5T=7)N("`P+@H@("`@("`@(
  1120. M("`@26X@86YY("!C87-E+"`@<W5B<V5Q=65N="!296%D*"ES(&%L=V%Y<R!RY
  1121. M971U<FX@,"X@(%=R:71E*"ES"B`@("`@("`@("!T;R!T:&ES(&9I;&4@87)E8
  1122. M(&YO="!A;&QO=V5D+"!A;F0@=&AE(')E<W5L="!I<R!U;F1E9FEN960N("`*>
  1123. M"@H@("`@("`@("`@("`@("!4:&4@;G5M97)I8R!A<F=U;65N=',@>6]U(&-A_
  1124. M;B!S=7!P;'D@=VET:"`@=&AE("!V87)I;W5S"B`@("`@("`@("!O<'1I;VYSW
  1125. M("!C86X@(&)E("!D96-I;6%L("`H;F\@('!R969I>"DL(&]C=&%L("AP<F5F8
  1126. M:7@@,"D@;W(*("`@("`@("`@(&AE>&%D96-I;6%L("AP<F5F:7@@,'@I+B!4#
  1127. M:&4@:&5X861E8VEM86P@9&EG:71S($$@=&AR;W5G:"`@1@H@("`@("`@("`@8
  1128. M;75S="!B92`@9VEV96X@(&EN('5P<&5R8V%S92X@($9O;&QO=VEN9R!T:&4@H
  1129. M;G5M8F5R+"!A('-C86QE"B`@("`@("`@("!F86-T;W(@;6%Y(&)E(&=I=F5NN
  1130. M(&EN(&QO=V5R8V%S92X@(%1H92!C=7)R96YT;'D@(')E8V]G;FEZ960*("`@'
  1131. M("`@("`@('-C86QE<R!A<F4@FS-M;2";,&UF;W(@;65G86)Y=&5S+"";,VUKM
  1132. M()LP;69O<B!K:6QO8GET97,L()LS;7,@FS!M9F]R('1R86-K9&ES:PH@("`@8
  1133. M("`@("`@<V5C=&]R<R!A;F0@FS-M8B";,&UF;W(@8GET97,N("!-=6QT:7!L.
  1134. M92!F86-T;W)S(&%R92!A;'-O(&%L;&]W960L"B`@("`@("`@("!W:&EC:"!S"
  1135. M=&%N9"!F;W(@=&AE('!R;V1U8W0@;V8@=&AE:7(@<F5S<&5C=&EV92!F86-T9
  1136. M;W)S+B`@"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@E
  1137. M("`M,BT@("`@("`@("`@("`@("`@("`@("`@(%)E;&5A<V4@,2XP"@H*("`@:
  1138. M("!21$8H-"D@("`@("`@("`@("`@("`@06UI9V$@4')O9W)A;6UE<B=S($UAD
  1139. M;G5A;"`@("`@("`@("`@("`@("`@4D1&*#0I"@H*("`@("`@("`@($9O;&QO+
  1140. M=VEN9R`@=&AE("!S97%U96YC92`@;V8@('-C86QE("!F86-T;W)S+"`@82`@K
  1141. M;F5W("!D:6=I=`H@("`@("`@("`@<VEG;FEF:65S('1H870@86YO=&AE<B!N6
  1142. M=6UB97(@9F]L;&]W<RX@(%1H870@;G5M8F5R(&ES(&%D9&5D"B`@("`@("`@!
  1143. M("!T;R!T:&4@=F%L=64@86QR96%D>2!C86QC=6QA=&5D+B`@5&AI<R!I<R!U,
  1144. M<V5F=6P@=&\@('-P96-I9GD*("`@("`@("`@(&$@=F%L=64@;V8@,C`@2R!PO
  1145. M;'5S(#,R(&)Y=&5S.B`R,&LS,BX@(`H*("`@("`@("`@("`@("`@06YY=&AI[
  1146. M;F<@=&AA="`@:7,@;F]T('!A<G0@;V8@82!N=6UB97(L(&DN92X@(&IU;FL@W
  1147. M;&EK90H@("`@("`@("`@<W5F9FEX97,@861D960@8GD@<V]M92!P<F]G<F%M5
  1148. M<RP@:7,@:6=N;W)E9"X@($%L<V\@(&%N>71H:6YG"B`@("`@("`@("!B971W^
  1149. M965N('1H92!C;VQO;B!O9B";,VU21$8Z()LP;6%N9"!T:&4@9FER<W0@<VQA.
  1150. M<V@@:7,@:6=N;W)E9"P@:6X*("`@("`@("`@(&-A<V4@('EO=2`@=VES:"`@`
  1151. M=&\@=7-E(&9I;&4@;F%M92!S>6YT87@@8V]M<&%T:6)L92!W:71H('1H90H@_
  1152. M("`@("`@("`@<F5S="!O9B!T:&4@<WES=&5M+B`@3VYL>2!T:&4@9FER<W0@2
  1153. M;&5T=&5R(&9O;&QO=VEN9R!A('-L87-H"B`@("`@("`@("!I<R`@<VEG;FEFC
  1154. M:6-A;G0L("!A;F0@(&UU<W0@(&)E("!F;VQL;W=E9"`@9&ER96-T;'D@(&)Y5
  1155. M("!A;GD*("`@("`@("`@(')E<75I<F5D(&%R9W5M96YT+B`@"@H@("`@("`@8
  1156. M("`@("`@("!9;W4@(&UA>2`@4F5A9"@I(&%N9"!7<FET92@I(&%N>2!N=6UB:
  1157. M97(@;V8@8GET97,@;VX@86YY"B`@("`@("`@("!O9F9S970N("!)9B!T:&4@G
  1158. M22]/(&ES(&YO="!S=6ET86)L>2!A;&EG;F5D+"!D871A(&ES("!C;W!I960*5
  1159. M("`@("`@("`@('1H<F]U9V@@82`@8G5F9F5R('!R:79A=&4@=&\@4D1&+B`@$
  1160. M0F5C875S92!T:&5R92!I<R!O;FQY(&]N90H@("`@("`@("`@<V5C=&]R("`@J
  1161. M8G5F9F5R+"`@(&%L;"`@(&EN8V]M:6YG("`@<&%C:V5T<R`@(&%R92`@("!H^
  1162. M86YD;&5D"B`@("`@("`@("!S>6YC:')O;F]U<VQY+B`@(%1H:7,@(&ES("!T8
  1163. M;R`@879O:60@:&%V:6YG(&UU;'1I<&QE($E/17AT5$0*("`@("`@("`@(')E-
  1164. M<75E<W1S(&]U='-T86YD:6YG+"!W:&EC:"`@;6%Y("!B96-O;64@('%U:71EN
  1165. M("!C;VUP;&EC871E9`H@("`@("`@("`@=VAE;B`@;75L=&EP;&4@(')E<75E/
  1166. M<W1S("!A<F4@(&]U='-T86YD:6YG(&]N('1H92!S86UE(&9I;&4N"B`@("`@^
  1167. M("`@("!4:&ES(&ES(&%L<V\@=&AE(&]N;'D@*'-I;7!L92D@=V%Y('1H870@C
  1168. M(&9U;&P@('-E<FEA;&ES871I;VX*("`@("`@("`@(&]F("!)+T\@('1H<F]UB
  1169. M9V@@FS-M4D1&.B";,&UC86X@8F4@9W5A<F%N=&5E9"`H=VAI8V@@<V5E;7,@I
  1170. M=&\@8F4@80H@("`@("`@("`@9V]O9"!T:&EN9RDN("`*"B`@("`@("`@("`@#
  1171. M("`@($EF('EO=2!W<FET92!A('!A<G1I86P@9&ES:R!B;&]C:RP@(&ET("!IM
  1172. M<R`@9FER<W0@(')E860*("`@("`@("`@(&EN=&\@('1H92!P<FEV871E(&)U.
  1173. M9F9E<BP@=&AE;B!M;V1I9FEE9"!A8V-O<F1I;F<@=&\@=&AE($DO3PH@("`@>
  1174. M("`@("`@<F5Q=65S="P@86YD('1H96X@=W)I='1E;B!B86-K+B`@268@>6]U/
  1175. M("!W<FET92`@;6%N>2`@;&ET=&QE"B`@("`@("`@("!P:65C97,L('1H:7,@5
  1176. M(&=E=',@=F5R>2!I;F5F9FEC:65N="X@($ET(&-A;FYO="!B92!O<'1I;6EZ^
  1177. M960*("`@("`@("`@('1H;W5G:"P@<VEN8V4@('-O;65B;V1Y("!E;'-E("!MX
  1178. M87D@('=R:71E("!T;R`@=&AE("!D:7-K("!I;@H@("`@("`@("`@8F5T=V5EQ
  1179. M;BX@(`H*("`@("`@("`@("`@("`@1F]R("!C;VUP871I8FEL:71Y("!W:71HM
  1180. M("!P<F]G<F%M<R`@=&AA="`@3&]C:R@I(&$@9FEL90H@("`@("`@("`@8F5FN
  1181. M;W)E("!O<&5N:6YG("!I="P@(&%S("`@<F5C;VUM96YD960@("!I;B`@('1HI
  1182. M92`@($%M:6=A1$]3"B`@("`@("`@("!$979E;&]P97(G<R`@36%N=6%L("`H:
  1183. M<V5E($QO8VLH*2!A;F0@3W!E;B@I*2P@>6]U(&-A;B!,;V-K*"D*("`@("`@U
  1184. M("`@("=F:6QE<R<@;VX@FS-M4D1&.B";,&TN(%1H92!R97-U;'1I;F<@1FEL.
  1185. M94QO8VL@:7,@(&9A:V4L("!H;W=E=F5R+@H@("`@("`@("`@270@(&ES;B=T'
  1186. M("!U<V5F=6P@(&%T("!A;&PL("!S:6YC92`@;F\@(&9U;F-T:6]N<R`@<F5Q>
  1187. M=6ER:6YG"B`@("`@("`@("!&:6QE3&]C:W,@87)E('-U<'!O<G1E9"X@("A/7
  1188. M;FQY(%5N3&]C:R@I(&%N9"`@1'5P3&]C:R@I+"`@;V8*("`@("`@("`@(&-O#
  1189. M=7)S92DN("`@(%-O;64@('!R;V=R86US("!M87D@(&YO="`@;&EK92`@=&AE3
  1190. M("`H861M:71T961L>0H@("`@("`@("`@=6YU<W5A;"D@<VET=6%T:6]N('1H5
  1191. M870@=&AE>2!S=6-C97-S9G5L;'D@:&%V92`@82`@;&]C:R`@8G5T"B`@("`@W
  1192. M("`@("!C86YN;W0@17AA;6EN92@I(&ET+B`@*%-E92!T:&4@8G5G<R!S96-T,
  1193. M:6]N*2X@(`H*("`@("";,6U%6$%-4$Q%4R`*("`@("`@("`@()LP;5EO=2`@(
  1194. M8V%N("!U<V4@('1H92";,VU21$8Z()LP;6EN=&5R9F%C92!I;B!C;VYJ=6YC!
  1195. M=&EO;B!W:71H(&$@9FEL90H@("`@("`@("`@87)C:&EV92!P<F]G<F%M(&QI0
  1196. M:V4@6F]O+B!4:&ES(&AA<R!T:&4@(&%D=F%N=&%G92`@=&AA="`@>6]U"B`@.
  1197. M("`@("`@("!H879E(&UO<F4@969F96-T:79E('-P86-E(&]N('EO=7(@9FQO!
  1198. M<'!Y('1H86X@=VAE;B!Y;W4@=W)I=&4*("`@("`@("`@('1H92`@87)C:&EV&
  1199. M92`@;VX@=&AE(&1I<VL@=7-I;F<@=&AE($]&4R`H3VQD($9I;&EN9R!3>7-T0
  1200. M96TI+@H@("`@("`@("`@06QS;RP@86-C97-S('=I;&P@8F4@9F%S=&5R(&)E+
  1201. M8V%U<V4@=&AE<F4@(&ES("!N;R`@;F5E9"`@9F]R"B`@("`@("`@("!E>'1EE
  1202. M;G-I;VX@(&)L;V-K<R!T;R!T96QL('=H97)E(&5A8V@@8FQO8VL@;V8@=&AEF
  1203. M(&9I;&4@:7,@;VX*("`@("`@("`@(&1I<VLN("`*("`@("`@("`@($9O<B!E2
  1204. M>&%M<&QE+"!T;R!A<F-H:79E(&$@;G5M8F5R(&]F(&9I;&5S(&9R;VT@('1HZ
  1205. M92`@8W5R<F5N=`H@("`@("`@("`@9&ER96-T;W)Y('1O(&$@<F%W(&9L;W!PV
  1206. M>3H@"@H@("`@("`@("`@("`@($UO=6YT(%)$1CH*("`@("`@("`@("`@("!:4
  1207. M;V\@82!21$8Z+V4@*BYC"@H@("`@("`@("`@5&AE("`N>F]O("!E>'1E;G-I_
  1208. M;VX@('1H870@(%IO;R`@861D<R`@=&\@('1H92`@9FEL92!N86UE(&ES"B`@M
  1209. M("`@("`@("!I9VYO<F5D+"!S:6YC92!I="!I<R!N;W0@82!V86QI9"!N=6UBS
  1210. M97(N("!4:&4@+V4@(&]P=&EO;B`@:7,*("`@("`@("`@(&YE8V5S<V%R>2`@F
  1211. M<VEN8V4@(%IO;R`@:7,@(&]N92`@;V8@('1H;W-E('!R;V=R86US('1H870@<
  1212. M=7-E<PH*"B`@("`@2V]S;6]3;V9T("`@("`@("`@("`@("`@("`@("`@("`@C
  1213. M+3,M("`@("`@("`@("`@("`@("`@("`@("!296QE87-E(#$N,`H*"B`@("`@;
  1214. M4D1&*#0I("`@("`@("`@("`@("`@($%M:6=A(%!R;V=R86UM97(G<R!-86YU'
  1215. M86P@("`@("`@("`@("`@("`@(%)$1B@T*0H*"B`@("`@("`@("!3965K*"ESX
  1216. M(')E;&%T:79E('1O('1H92!E;F0@;V8@=&AE(&9I;&4N("`*("`@("`@("`@E
  1217. M($EF('EO=2!M:6=H="!L871E<B!W86YT('1O(&%D9"!S;VUE(&UO<F4@9FELE
  1218. M97,@=&\@('1H:7,@(')A=PH@("`@("`@("`@87)C:&EV92P@>6]U("!N965D.
  1219. M("!T;R`@:VYO=R`@=&AE("!E;F0M;V8M9FEL92`@;6%R:RX@("`@66]U"B`@)
  1220. M("`@("`@("!R971R:65V92!T:&ES('9A;'5E('5S:6YG(`H*("`@("`@("`@5
  1221. M("`@("!4>7!E(#P@4D1&.B]%(&]P="!H"@H@("`@("`@("`@5&AI<R!M:6=HT
  1222. M="!R97-U;'0@:6X@=&AE('9A;'5E(#!X,3=!0B!B96EN9R!D:7-P;&%Y960NM
  1223. M("!7:&5N"B`@("`@("`@("!Y;W4@;&%T97(@=V%N="!T;R!A9&0@<V]M92!MX
  1224. M;W)E(&9I;&5S+"!D;R`*"B`@("`@("`@("`@("`@6F]O(&$@4D1&.B]E,'@QH
  1225. M-T%"("HN:`H*("`@("`@("`@($YO=&4@=&AA="!T:&4@:&5X861E8VEM86P@K
  1226. M9&EG:71S($$@('1H<F]U9V@@($8@(&UU<W0@(&)E("!I;@H@("`@("`@("`@=
  1227. M=7!P97(@8V%S92X@(`H@("`@("`@("`@5&\@(&QI<W0@('1H92!C;VYT96YT[
  1228. M<R!O9B!T:&4@<F%W(&%R8VAI=F4L('EO=2!U;F9O<G1U;F%T96QY"B`@("`@(
  1229. M("`@("!C86YN;W0@=7-E(%IO;R!I='-E;&8L('-I;F-E(&ET("AF;W(@=6YKG
  1230. M;F]W;B!R96%S;VYS*2!A;'=A>7,*("`@("`@("`@(&EN<VES=',@;VX@9&]IG
  1231. M;F<@86X@($5X86UI;F4H,BDN("!4:&ES("!I<R`@82`@;F]N+7-U<'!O<G1E+
  1232. M9`H@("`@("`@("`@9G5N8W1I;VXN("`@26YS=&5A9"P@('EO=2`@;6%Y("!UO
  1233. M<V4@0F]O>BP@=&AE(&)A<F4M8F]N97,@>F]O"B`@("`@("`@("!E>'1R86-T:
  1234. M;W(O;&ES=&5R+B`@270@<V5E;7,@=&AA="!";V]Z('5S=6%L;'D@8V%N(&1E`
  1235. M=&5C="!T:&4*("`@("`@("`@(&QO9VEC86P@96YD(&]F(&%N(&%R8VAI=F4@3
  1236. M9G)O;2!I=',@8V]N=&5N=',N("`*"B`@("`@("`@("`@("`@($EF("!Y;W4@`
  1237. M(&AA=F4@(&$@(&1I<V%S<V5M8FQE<B`@('1H870@("!A8V-E<'1S("`@9FEL2
  1238. M97,*("`@("`@("`@(&-O;G1A:6YI;F<@(&UE;6]R>2`@9'5M<',L('EO=2!CZ
  1239. M86X@9&ES87-S96UB;&4@=&AE(&)O;W1B;&]C:PH@("`@("`@("`@;V8@82!D?
  1240. M:7-K.B`*"B`@("`@("`@("`@("`@1&ES07-S96UB;&4@4D1&.B]L,6L*"@H@L
  1241. M("`@()LQ;5-!35!,12!-3U5.5$Q)4U0@"B`@("`@("`@("";,&U21$8Z("`@"
  1242. M($AA;F1L97(@/2!L.E)$1BU(86YD;&5R"B`@("`@("`@("`@("`@("`@($1E[
  1243. M=FEC92`]('1R86-K9&ES:RYD979I8V4*("`@("`@("`@("`@("`@("`@56YIX
  1244. M="`](#$*("`@("`@("`@("`@("`@("`@1FQA9W,@/2`P"B`@("`@("`@("`@P
  1245. M("`@("`@(%-T86-K<VEZ92`](#0P.38*("`@("`@("`@("`@("`@("`@4')I6
  1246. M;W)I='D@/2`T"B`@("`@("`@("`@("`@("`@($=L;V)696,@(#T@+3$*("`@Y
  1247. M("`@("`@(",*"B`@("`@FS%M4$%#2T544R!355!03U)4140@"B`@("`@("`@+
  1248. M("";,&V;,VU!0U1)3TY?1DE.1%])3E!55*";,&V@H*!);7!L96UE;G1S("`@6
  1249. M("!/<&5N*"DN("`@("!$;V5S("`@("`@86X*("`@("`@("`@("`@("`@("`@5
  1250. M("`@("`@("`@("`@($]P96Y$979I8V4H*2X@(`H@("`@("`@("`@FS-M04-4>
  1251. M24].7T9)3D1?3U544%54H)LP;:"@26UP;&5M96YT<R`@("`@($]P96XH*2X@=
  1252. M("`@($1O97,@("`@(&%N"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@D
  1253. M("!/<&5N1&5V:6-E*"DN("`@("`@("!3>6YO;GEM("`@("`@("!F;W(*("`@/
  1254. M("`@("`@("`@("`@("`@("`@("`@("`@("`@($%#5$E/3E]&24Y$7TE.4%54M
  1255. M+B`@"B`@("`@("`@("";,VU!0U1)3TY?14Y$H)LP;:"@H*"@H*"@H*!);7!L1
  1256. M96UE;G1S("!#;&]S92@I+B!$;V5S(&$@0TU$7U501$%412P*("`@("`@("`@9
  1257. M("`@("`@("`@("`@("`@("`@("`@(&$@5$1?34]43U(L('1H96X@82!#;&]SV
  1258. M941E=FEC92@I+B`@"B`@("`@("`@("";,VU!0U1)3TY?4D5!1*";,&V@H*"@*
  1259. MH*"@H*!);7!L96UE;G1S(%)E860H*2X@1&]E<R!A;B!%5$1?4D5!1"X@(`H@#
  1260. M("`@("`@("`@FS-M04-424].7U=2251%H)LP;:"@H*"@H*"@26UP;&5M96YT&
  1261. M<R`@5W)I=&4H*2X@($1O97,@("AM87EB92`@(&%N"B`@("`@("`@("`@("`@W
  1262. M("`@("`@("`@("`@("`@("!%5$1?4D5!1"!A;F0@=&AE;BD@86X@151$7U=2W
  1263. M251%+B`@"B`@("`@("`@("";,VU!0U1)3TY?4T5%2Z";,&V@H*"@H*"@H*!);
  1264. M;7!L96UE;G1S(%-E96LH*2X@(`H@("`@("`@("`@FS-M04-424].7TQ/0T%41
  1265. M15]/0DI%0U2@FS!M26UP;&5M96YT<R`@3&]C:R@I+B`@06QW87ES('-U8V-E]
  1266. M961S(&EF"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!M96UO<GD@.
  1267. M8V%N(&)E("!O8G1A:6YE9"`@9F]R("!A("!S=')U8W0*("`@("`@("`@("`@V
  1268. M("`@("`@("`@("`@("`@("`@($9I;&5,;V-K+B`@"B`@("`@("`@("";,VU!=
  1269. M0U1)3TY?0T]065]$25*@FS!MH*"@H*!);7!L96UE;G1S($1U<$QO8VLH*2X@<
  1270. M(`H@("`@("`@("`@FS-M04-424].7T92145?3$]#2Z";,&V@H*"@26UP;&5MH
  1271. M96YT<R!5;DQO8VLH*2X@(`H@("`@("`@("`@FS-M04-424].7T1%3$5415]/H
  1272. M0DI%0U2@FS!M26UP;&5M96YT<R`@("`@1&5L971E1FEL92@I+B`@("`@06QW4
  1273. M87ES"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!S=6-C965D<RX@4
  1274. M($1O97,@;F]T:&EN9RX@(`H@("`@("`@("`@FS-M04-424].7T1)1:";,&V@<
  1275. MH*"@H*"@H*"@56YL;V%D<R!T:&4@:&%N9&QE<B!F<F]M("!M96UO<GD@(&%F)
  1276. M=&5R"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@("`M;
  1277. M-"T@("`@("`@("`@("`@("`@("`@("`@(%)E;&5A<V4@,2XP"@H*("`@("!2!
  1278. M1$8H-"D@("`@("`@("`@("`@("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A6
  1279. M;"`@("`@("`@("`@("`@("`@4D1&*#0I"@H*("`@("`@("`@("`@("`@("`@+
  1280. M("`@("`@("`@("`@(&%L;"!F:6QE<R!H879E(&)E96X@8VQO<V5D+B`@"B`@<
  1281. M("`@("`@("";,VU!0U1)3TY?4D5.04U%7T1)4TN@FS!MH*!3>6YO;GEM("!F5
  1282. M;W(@($%#5$E/3E]$244N("!9;W4@(&-A;B!U<V4*("`@("`@("`@("`@("`@$
  1283. M("`@("`@("`@("`@("`@("=296QA8F5L("!21$8Z("!X>'@G("!T;R`@('5NI
  1284. M;&]A9"`@('1H90H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@:&%NB
  1285. M9&QE<B!F<F]M(&UE;6]R>2X@(`H*("`@("";,6U$24%'3D]35$E#4R`*("`@1
  1286. M("`@("`@()LP;5!L96YT>2`@=VAE;B`@8V]M<&EL960@('=I=&@@(&1E8G5G6
  1287. M9VEN9R`@96YA8FQE9"P@(&]T:&5R=VES90H@("`@("`@("`@;F]N92X@(`H*R
  1288. M("`@("";,6U215154DX@0T]$15,@"B`@("`@("`@("";,&U/8G1A:6YE9"!VE
  1289. M:6$@26]%<G(H*2X@(`H@("`@("`@("`@FS-M15)23U)?4D5!1%]04D]414-44
  1290. M142@FS!M;W*@FS-M15)23U)?5U))5$5?4%)/5$5#5$5$H)LP;7=H96X@82!RW
  1291. M96%D(&]R"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(&$@=W)IH
  1292. M=&4@97)R;W(@:7,@9&5T96-T960N("!.;R`@;W1H97(*("`@("`@("`@("`@8
  1293. M("`@("`@("`@("`@("`@("`@("`@97)R;W(@8V]D92!S965M<R!T;R!C;VUE)
  1294. M(&-L;W-E+B`@"B`@("`@("`@("";,VU%4E)/4E]$25-+7T953$R@FS!MH*"@'
  1295. MH*"@H'=H96X@(&%N("!A='1E;7!T("!I<R`@;6%D92`@=&\@=W)I=&4*("`@+
  1296. M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@8F5Y;VYD('1H92!I;F1IF
  1297. M8V%T960@<&AY<VEC86P@(&1E=FEC90H@("`@("`@("`@("`@("`@("`@("`@X
  1298. M("`@("`@("`@("!L:6UI="X@(`H@("`@("`@("`@FS-M15)23U)?4T5%2U]%G
  1299. M4E)/4J";,&V@H*"@H*!F;W(@:6YV86QI9"!3965K*"ES+B`@"B`@("`@("`@/
  1300. M("";,VU%4E)/4E].3U]&4D5%7U-43U)%H)LP;:"@H&%T('-T87)T=7`@:68@]
  1301. M8G5F9F5R(&UE;6]R>2!C86YN;W0@8F4*("`@("`@("`@("`@("`@("`@("`@G
  1302. M("`@("`@("`@("`@86QL;V-A=&5D+"!O<B!W:&5N('1H97)E(&ES(&YO(&UE+
  1303. M;6]R>0H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!F;W(@82!&?
  1304. M:6QE3&]C:RP@86X@24]%>'141"P@971C+B`@"B`@("`@("`@("";,VU%4E)/2
  1305. M4E]!0U1)3TY?3D]47TM.3U=.H)LP;69O<B!U;FMN;W=N('!A8VME=',N("`*]
  1306. M"B`@("`@FS%M0E5'4R`*("`@("`@("`@()LP;41O:6YG("!M=6QT:7!L92`@3
  1307. M<W5C8V5S<VEV92`@5W)I=&4H*7,@;V8@82!F97<@8GET97,@:7,@=F5R>0H@W
  1308. M("`@("`@("`@:6YE9F9I8VEE;G0N("!4:&4@<V%M92!I<R!T<G5E(&9O<B!2N
  1309. M96%D*"DL('1H;W5G:"`@;&5S<R`@<V\N"B`@("`@("`@("!4:&ES("!I<R`@;
  1310. M8F5C875S92`@86QL("!D979I8V4@($DO3R`@9V]E<R`@=&AR;W5G:"`@=&AEX
  1311. M('-A;64*("`@("`@("`@(&)U9F9E<BX@(`H@("`@("`@("`@3F]T(')E86QLC
  1312. M>2!A(&)U9R!O9B";,VU21$8Z()LP;6)U="!A;FYO>6EN9R`@86YY=V%Y.B`@W
  1313. M57-I;F<@("A!<G`I"B`@("`@("`@("!465!%("!21$8Z("!/4%0@($@L("!47
  1314. M>7!E("!,;V-K*"ES("!T:&4@(&9I;&4L('1H96X@=V%N=',@=&\*("`@("`@1
  1315. M("`@($5X86UI;F4H*2!I="P@<')E<W5M86)L>2!T;R!S964@:68@:70@:7,@-
  1316. M(&YO="`@82`@9&ER96-T;W)Y+`H@("`@("`@("`@8G5T('1H870@(&ES("!N#
  1317. M;W0@(&$@<W5P<&]R=&5D(&9U;F-T:6]N+B`@5&AE;B!I="!F;W)G971S('1OG
  1318. M"B`@("`@("`@("!5;DQO8VLH*2!T:&4@(&QO8VL@(&%G86EN+"`@=VAI8V@@0
  1319. M('=A<W1E<R`@<V]M92`@;65M;W)Y("!A;F0*("`@("`@("`@('!R;VAI8FETB
  1320. M<R`@=&AE("!H86YD;&5R("!F<F]M("!B96EN9R`@=6YL;V%D960@(&9R;VT@K
  1321. M;65M;W)Y+@H@("`@("`@("`@0F5W87)E(&]F(&]T:&5R('!R;V=R86US('1HE
  1322. M870@86-T('5N<&]L:71E('=H96X@9F%C960@=VET:"!A"B`@("`@("`@("!&/
  1323. M:6QE3&]C:R!T:&%T('1H97D@8V%N;F]T($5X86UI;F4H*2X@(`H@("`@("`@A
  1324. M("`@5&AE(&UO=&]R(&]F('1H92!D<FEV92!S:&]U;&0@<&5R:6]D:6-A;&QYR
  1325. M(&)E('1U<FYE9"!O9F8N("`*("`@("`@("`@($UO<F4@('1I;64@('=A<R`@Y
  1326. M('-P96YT("`@<')O;V9R96%D:6YG("`@=&AE("`@;6%N=6%L("`@=&AA;@H@>
  1327. M("`@("`@("`@<')O;V9R96%D:6YG('1H92!P<F]G<F%M+B`@"@H@("`@()LQ'
  1328. M;5-%12!!3%-/(`H@("`@("`@("`@FS!M6F]O*#$I+"`@0F]O>B@Q*2P@($%R<
  1329. M8R@Q*2P@('1A<B@Q*2P@(&%R*#$I+"!T<F%C:V1I<VLN9&5V:6-E"B`@("`@O
  1330. M("`@("`H4F]M("!+97)N86P@(%)E9F5R96YC92`@36%N=6%L.B`@3&EB<F%R6
  1331. M:65S("`@86YD("`@1&5V:6-E<RP*("`@("`@("`@($%U=&]D;V-S*2P@("!!E
  1332. M;6EG841/4R`@(&UA;G5A;"P@("!-871T97<@("!$:6QL;VXG<R`@(%!)4$4Z$
  1333. M+`H@("`@("`@("`@8V]M<"YS;W5R8V5S+FUA='0M9&EL;&]N(&EN(&=E;F5R2
  1334. M86PN("`*"@H*"@H*"@H*"@H*"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@@
  1335. M("`@("`@("`@("`@("`M-2T@("`@("`@("`@("`@("`@("`@("`@(%)E;&5A8
  1336. (<V4@,2XP"@H@[
  1337. ``
  1338. end
  1339. size 15983
  1340. SHAR_EOF
  1341. #    End of shell archive
  1342. exit 0
  1343. -- 
  1344. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  1345. Have five nice days.
  1346.